﻿@using Seal.Model;
@{
    ReportTask task = Model;

    task.TemplateDescription = "Download/Upload a file from/to a file server (FTP, SFTP, SCP).";

    //Parameters for this task
    task.Parameters.Add(new Parameter() { Name = "action", Value = "DW", DisplayName = "Action", Description = "Download/Upload action to perform.", Enums = new string[] { "DW|Download a file", "UP|Upload a file"}, UseOnlyEnumValues = true });
    task.Parameters.Add(new Parameter() { Name = "protocol", Value = "FTP", DisplayName = "Protocol", Description = "Protocol to connect to the server.", Enums = new string[] { "FTP", "SFTP", "SCP" }, UseOnlyEnumValues = true });
    task.Parameters.Add(new Parameter() { Name = "host_name", Value = "127.0.0.1", DisplayName = "Host name", Description = "The host name of the server."+ ReportTask.TranslatedParameterDescription });
    task.Parameters.Add(new Parameter() { Name = "port", NumericValue = 0, DisplayName = "Port number", Description = "For FTP Protocol, port number used to connect to the server (e.g. 21 for FTP or implicit FTPS, 990 for FTPS, etc.). A value of 0 means an automatic detection and connection." });
    task.Parameters.Add(new Parameter() { Name = "user_name", Value = "", DisplayName = "User name", Description = "The user name used to connect to the server."+ ReportTask.TranslatedParameterDescription });
    task.Parameters.Add(new Parameter() { Name = "password", Value = "", DisplayName = "Password", Description = "The password used to connect to the server."+ ReportTask.TranslatedParameterDescription });
    task.Parameters.Add(new Parameter() { Name = "remote_file", Value = "", DisplayName = "Remote file path", Description = "The remote file path to download or upload."+ ReportTask.TranslatedParameterDescription });
    task.Parameters.Add(new Parameter() { Name = "local_file", Value = "", DisplayName = "Local file path", Description = "The local file path to download or upload."+ ReportTask.TranslatedParameterDescriptionFull, Enums = new string[] {  @"%SEALREPOSITORY%/Databases/excel samples.zip", @"%SEALREPOSITORY%/TestFiles/Download/excel samples.zip", ReportTask.ParentExecResultKeyword, ReportTask.ExecInputKeyword }, UseOnlyEnumValues = false});

    task.Script = @"@using FluentFTP
@using Renci.SshNet
@using System.IO

@{
    ReportTask task = Model;
    Report report = task.Report;
    
    var download = task.GetValue(""action"") == ""DW"";
    var protocol = task.GetValueTranslated(""protocol"");
    var hostName = task.GetValueTranslated(""host_name"");
    var port = task.GetNumericValue(""port"");;
    var userName = task.GetValueTranslated(""user_name"");
    var password = task.GetValueTranslated(""password"");
    var remoteFile = task.GetValueTranslated(""remote_file"");
    var localFile = task.GetValueTranslated(""local_file"");

    if (string.IsNullOrEmpty(localFile)) {
        throw new Exception(""Local path is empty."");
    }
    if (string.IsNullOrEmpty(remoteFile)) {
        throw new Exception(""Remote path is empty."");
    }

    if (download) {
        task.LogMessage($""Downloading '{remoteFile}' to '{localFile}'"");
    }
    else {
        if (!File.Exists(localFile)) {
            throw new Exception(""Invalid local path: {localFile}"");
        }
        task.LogMessage($""Uploading '{localFile}' to '{remoteFile}'"");
    }

    if (protocol == ""FTP"")
    {
        //Refer to https://github.com/robinrodricks/FluentFTP
        using (var client = new FtpClient(hostName, userName, password)) {
            client.Config.EncryptionMode = FtpEncryptionMode.Auto;
            client.Config.ValidateAnyCertificate = true;
            if (port == 0) {
                client.AutoConnect();
            }
            else {
                client.Port = port;
                //SSL Configuration can be defined here
                /*
                client.Config.EncryptionMode = FtpEncryptionMode.Explicit;
                client.Config.SslProtocols = SslProtocols.Tls12;
                client.ValidateCertificate += new FtpSslValidation(delegate (FluentFTP.Client.BaseClient.BaseFtpClient control, FtpSslValidationEventArgs e)
                {
                    if (e.PolicyErrors != System.Net.Security.SslPolicyErrors.None) {
                        e.Accept = false;
                    }
                    else {
                        e.Accept = true;
                    }
                });
                */
                client.Connect();
            }
            
            try {
                FtpStatus status;
                if (download) {            
                    status = client.DownloadFile(localFile, remoteFile);
                }
                else {
                    status = client.UploadFile(localFile, remoteFile);
                }
                if (status != FtpStatus.Success) throw new Exception($""Unable to transfer file '{localFile}','{remoteFile}'"");
            }
            finally {
                client.Disconnect();
            }
        }
    }
    else if (protocol == ""SFTP"")
    {
        //Refer to https://github.com/sshnet/SSH.NET
        using (var sftp = new SftpClient(hostName, port, userName, password))
        {
            sftp.Connect();
            using (Stream fileStream = File.Create(localFile))
            {
                if (download) {            
                    sftp.DownloadFile(remoteFile, fileStream);
                }
                else {
                   sftp.UploadFile(fileStream, remoteFile);
                }
            }
            sftp.Disconnect();
        }
    }
    else if (protocol == ""SCP"")
    {
        //Refer to https://github.com/sshnet/SSH.NET
        using (var scp = new ScpClient(hostName, port, userName, password))
        {
            scp.Connect();
            using (Stream fileStream = File.Create(localFile))
            {
                if (download) {            
                    scp.Download(remoteFile, fileStream);
                }
                else {
                    scp.Upload(fileStream, remoteFile);
                }
            }
            scp.Disconnect();
        }
    }
    //Set result
    task.ExecResult = download ? localFile : remoteFile;
}
";

    task.BodyScript = ReportTask.BodyScriptTemplate;
}
